package com.netscenery.yang.model;

import org.jdom2.*;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import com.netscenery.util.*;
import com.netscenery.yang.YangKeyword;
import com.netscenery.yang.YangStatement;
import com.netscenery.yang.designer.LeafFieldMap;
import com.netscenery.yang.designer.MapInfo;

public class Include extends ModelElement{

	private String revisionDate;
	private SubModule include;
	
	/**
	 * constructor
	 * @param name
	 */
	public Include(Env env,String name){
		if (null == env){
			return;
		}
		
		if (null == name){
			return;
		}
		setEnv(env);
		setName(name);
		Module m = this.env.getModule(name);
		if (null == m){
			return;
		}
		if (m instanceof SubModule){
			this.setInclude((SubModule)m);
		}
		else{
			return;
		}
	}
	
	public Include (Env env,SubModule include){
		if (null == env){
			return;
		}
		if (null == include){
			return;
		}
		setEnv(env);
		setInclude(include);
		setName(include.getName());
		this.env.addSubModule(include);
	}
	
	public Include(){
		super();
	}
	
	public String getName() {
		return name;
	}

	public String getRevisionDate() {
		return revisionDate;
	}
	public void setRevisionDate(String revisionDate) {
		if (null == revisionDate){
			return;
		}
		if (!Revision.checkRevisionDate(revisionDate)){
			return;
		}
		if (null != this.include){
			if (null == include.getRevision(revisionDate)){
				return;
			}
		}
		this.revisionDate = revisionDate;
	}


	/**
	 * @return the s
	 */
	public SubModule getInclude() {
		return include;
	}

	/**
	 * @param s the s to set
	 */
	public void setInclude(SubModule s) {
		this.include = s;
		this.setName(s.getName());
	}

	/**
	 * ��Include��ת����XML��ʽ
	 * @return
	 */
	public Element toXML(){		
		
		if (null == this.name){
			return null;
		}
		Element includeElement = new Element(XMLTag.XML_TAG_INCLUDE);
		Element name = new Element("name");
		name.setText(this.name);
		includeElement.addContent(name);
		if (null != this.revisionDate){
			Element revisionDate = new Element(XMLTag.XML_TAG_REVISIONDATE);
			revisionDate.setText(this.revisionDate);
			includeElement.addContent(revisionDate);
		}
		
		return includeElement;
		
	}
	

	@Override
	public YangStatement toYang() {
		if (null == this.name){
			return null;
		}
		YangStatement statement = new YangStatement(YangStatement.YANG_STATEMENT_INCLUDE,
				this.name);
		if (null != this.revisionDate) {
			YangStatement subElement = new YangStatement(
					YangStatement.YANG_STATEMENT_REVISIONDATE, this.revisionDate);
			statement.addChild(subElement);
		}

		return statement;

	}

	@Override
	public int readXML(Element element) {
		if (null == element){
			return MODELELEMENT_OK;
		}
		if (element.getName().equals(XMLTag.XML_TAG_REVISIONDATE)){
			this.setRevisionDate(element.getText());
		}
		else if (element.getName().equals(XMLTag.XML_TAG_NAME)){
			return MODELELEMENT_OK;
		}	
		else {
			return MODELELEMENT_FAIL;
		}
		
		return MODELELEMENT_OK;

	}

	@Override
	public int readYANG(YangStatement statement) {
		if (null == statement){
			return MODELELEMENT_OK;
		}
		if (statement.getKeyword().equals(YangStatement.YANG_STATEMENT_REVISIONDATE)){
			this.setRevisionDate(statement.getArgument());
		}
		else {
			return MODELELEMENT_FAIL;
		}
		
		return MODELELEMENT_OK;

	}

	@Override
	public Validator validate() {
		Validator validator = new Validator();
		if (isNullString(name)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.COMMON_INVALIDNAME));
		}
		else if (null == this.include){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,"the module to be included is not exists."));
		}
		else {
			if (!this.include.getName().equals(this.name)){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.COMMON_INVALIDNAME));
			}
			
			if (!isNullString(revisionDate)){
				if (!Revision.checkRevisionDate(revisionDate)){
					validator.setIsValid(false);
					validator.addMsg(new Message(this,ErrTag.ERROR,"invalid revision-date."));
				}
				
				if (null == include.getRevision(revisionDate)){
					validator.setIsValid(false);
					validator.addMsg(new Message(this,ErrTag.ERROR,"invalid revision-date."));
				}
			}
		}
		
		
		Validator sValidator = super.validate();
		validator.copy(sValidator);
		return validator;
	}

	@Override
	public boolean isFieldMandatory(String field) {
		// TODO Auto-generated method stub
		return false;
	}

	
	public  MapInfo getMapInfo() throws SecurityException, NoSuchMethodException {
		MapInfo mapInfo = new MapInfo();
		mapInfo.setClazz(Include.class);
		
//		LeafFieldMap module = new LeafFieldMap();
//		module.setElementClass(MainModule.class);
//		module.setFieldName("importedModule");
//		module.setDisplayName("module");
//		module.setMandatory(true);
//		mapInfo.addBasicField(module);
		
		LeafFieldMap name = new LeafFieldMap();
		name.setFieldName("name");
		name.setMandatory(true);
		mapInfo.addBasicField(name);
				
		LeafFieldMap revisionDate = new LeafFieldMap();
		revisionDate.setFieldName("revisionDate");
		revisionDate.setDisplayName("revision-date");
		mapInfo.addBasicField(revisionDate);
		
		
		return mapInfo;
	}

	@Override
	public Element toYin() {
		if (null == this.name){
			return null;
		}
		Element statement = new Element(YangStatement.YANG_STATEMENT_INCLUDE,env.getNs());
		Attribute module = new Attribute(YangKeyword.MODULE.getKeyword(),this.name);
		statement.setAttribute(module);
		if (!isNullString(revisionDate)){
			Element revisionDateElement = new Element(XMLTag.XML_TAG_REVISIONDATE,env.getNs());
			Attribute date = new Attribute("date",this.revisionDate);
			revisionDateElement.setAttribute(date);
			statement.addContent(revisionDateElement);
		}

		return statement;
	}

	@Override
	public int readYin(Element statement) throws ModelException {
		if (null == statement){
			return MODELELEMENT_OK;
		}
		//revisionDate
		else if (statement.getName().equals(YangStatement.YANG_STATEMENT_REVISIONDATE)){
			String value = statement.getAttributeValue("date");
			if (null == value){
				return MODELELEMENT_FAIL;
			}
			this.setRevisionDate(value);
		}
		else {
			
			return MODELELEMENT_FAIL;
		}
		
		return MODELELEMENT_OK;
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		
	}


	
}
